home *** CD-ROM | disk | FTP | other *** search
/ PLAYymate for OS/2 / Playmate for OS2.iso / p4os2008 / ckrdraw.c < prev    next >
C/C++ Source or Header  |  1990-09-01  |  39KB  |  1,171 lines

  1. /*--------------------------------------------------------
  2.    CKRDRAW.C -- Ckd Board Drawing Functions, Version 0.40
  3.                 (c) 1990, Charles Petzold
  4.   --------------------------------------------------------*/
  5.  
  6. #define INCL_WIN
  7. #define INCL_GPI
  8. #include <os2.h>
  9. #include <stdlib.h>
  10. #include "checkers.h"
  11. #include "ckrdraw.h"
  12.  
  13.      /*----------------------------------------
  14.         Defines for board and piece dimensions
  15.        ----------------------------------------*/
  16.  
  17. #define BRD_HORZFRONT        500
  18. #define BRD_HORZBACK         350
  19. #define BRD_VERT             300
  20. #define BRD_EDGE              75
  21. #define BRD_HORZMARGIN       250
  22. #define BRD_FRONTMARGIN      250
  23. #define BRD_BACKMARGIN       250
  24. #define PIECE_XAXIS          (BRD_HORZBACK - 50)
  25. #define PIECE_YAXIS          (BRD_VERT - 50)
  26. #define PIECE_HEIGHT          50
  27.  
  28.      /*-------------------------------------
  29.         Global variables external to module
  30.        -------------------------------------*/
  31.  
  32. extern HAB hab ;
  33.  
  34.      /*-------------------------------------
  35.         Global variables internal to module
  36.        -------------------------------------*/
  37.  
  38.                // Background, board, and piece colors
  39.  
  40. static LONG clrBackground  = CLR_CYAN ;
  41. static LONG clrBlackSquare = CLR_DARKGREEN ;
  42. static LONG clrWhiteSquare = CLR_PALEGRAY ;
  43. static LONG clrBlackPiece  = CLR_RED ;
  44. static LONG clrWhitePiece  = CLR_WHITE ;
  45.  
  46.                // Text strings for saving colors to OS2.INI
  47.  
  48. static CHAR szApplication []    = "Checkers" ;
  49. static CHAR szClrBackground []  = "Background Color" ;
  50. static CHAR szClrBlackSquare [] = "Black Square Color" ;
  51. static CHAR szClrWhiteSquare [] = "White Square Color" ;
  52. static CHAR szClrBlackPiece []  = "Black Piece Color" ;
  53. static CHAR szClrWhitePiece []  = "White Piece Color" ;
  54.  
  55.                // Original viewport for adjusting board to window size
  56.  
  57. static RECTL rclOrigViewport ;
  58.  
  59.                // Bitmaps for drawing pieces
  60.  
  61. static HDC     hdcMemory, hdcMemory2 ;
  62. static HPS     hpsMemory, hpsMemory2 ;
  63. static HBITMAP ahbmPiece[2][2], ahbmMask[2], ahbmSave[2], ahbmMove[2] ;
  64. static SIZEL   sizlPiece[2], sizlMove[2] ;
  65.  
  66.      /*-------------------------------------------------------------
  67.         CkdQueryBoardDimensions: Obtains size of board with margins
  68.        -------------------------------------------------------------*/
  69.  
  70. VOID CkdQueryBoardDimensions (SIZEL *psizlPage)
  71.      {
  72.      psizlPage->cx = 8 * BRD_HORZFRONT + 2 * BRD_HORZMARGIN ;
  73.      psizlPage->cy = 8 * BRD_VERT + BRD_FRONTMARGIN + BRD_BACKMARGIN ;
  74.      }
  75.  
  76.      /*-----------------------------------------------------------
  77.         CkdQuerySquareOrigin: Obtains lower left corner of square
  78.        -----------------------------------------------------------*/
  79.  
  80. static VOID CkdQuerySquareOrigin (SHORT x, SHORT y, POINTL *pptl)
  81.      {
  82.      pptl->x = BRD_HORZMARGIN + y * (BRD_HORZFRONT - BRD_HORZBACK) / 2 +
  83.                     x * (y * BRD_HORZBACK + (8 - y) * BRD_HORZFRONT) / 8 ;
  84.  
  85.      pptl->y = BRD_FRONTMARGIN + y * BRD_VERT ;
  86.      }
  87.  
  88.      /*-----------------------------------------------------
  89.         CkdQuerySquareCoords: Obtains coordinates of square
  90.        -----------------------------------------------------*/
  91.  
  92. static VOID CkdQuerySquareCoords (SHORT x, SHORT y, POINTL aptl[])
  93.      {
  94.      CkdQuerySquareOrigin (x,     y,     aptl + 0) ;
  95.      CkdQuerySquareOrigin (x + 1, y,     aptl + 1) ;
  96.      CkdQuerySquareOrigin (x + 1, y + 1, aptl + 2) ;
  97.      CkdQuerySquareOrigin (x,     y + 1, aptl + 3) ;
  98.      }
  99.  
  100.      /*-----------------------------------------------
  101.         CkdDrawBoardSquare: Draws one square of board
  102.        -----------------------------------------------*/
  103.  
  104. static LONG CkdDrawBoardSquare (HPS hps, SHORT x, SHORT y)
  105.      {
  106.      AREABUNDLE abnd ;
  107.      LINEBUNDLE lbnd ;
  108.      LONG       lReturn ;
  109.      POINTL     aptl[4] ;
  110.  
  111.      GpiSavePS (hps) ;
  112.  
  113.      if (x < 0 || x >= 8 || y < 0 || y >= 8)
  114.           {
  115.           GpiSetColor (hps, clrBackground) ;
  116.           }
  117.      else
  118.           {
  119.           lbnd.lColor = CLR_BLACK ;
  120.           GpiSetAttrs (hps, PRIM_LINE, LBB_COLOR, 0L, &lbnd) ;
  121.  
  122.           abnd.lColor = (x + y) & 1 ? clrWhiteSquare : clrBlackSquare ;
  123.           GpiSetAttrs (hps, PRIM_AREA, LBB_COLOR, 0L, &abnd) ;
  124.           }
  125.  
  126.      GpiBeginArea (hps, BA_ALTERNATE | BA_BOUNDARY) ;
  127.  
  128.      CkdQuerySquareCoords (x, y, aptl) ;
  129.      GpiMove (hps, aptl + 3) ;
  130.      GpiPolyLine (hps, 4L, aptl) ;
  131.      lReturn = GpiEndArea (hps) ;
  132.  
  133.      GpiRestorePS (hps, -1L) ;
  134.  
  135.      return lReturn ;
  136.      }
  137.  
  138.      /*----------------------------------------------------
  139.         CkdDrawAllBoardSquares: Draws all squares of board
  140.        ----------------------------------------------------*/
  141.  
  142. static LONG CkdDrawAllBoardSquares (HPS hps)
  143.      {
  144.      SHORT x, y ;
  145.  
  146.      for (y = 0 ; y < 8 ; y++)
  147.           for (x = 0 ; x < 8 ; x++)
  148.                if (CkdDrawBoardSquare (hps, x, y) == GPI_HITS)
  149.                     return MAKELONG (x, y) ;
  150.  
  151.      return MAKELONG (-1, -1) ;
  152.      }
  153.  
  154.      /*------------------------------------------
  155.         CkdRenderPiece: Draws piece PS at (0, 0)
  156.        ------------------------------------------*/
  157.  
  158. static VOID CkdRenderPiece (HPS hps, LONG lColor, LONG lColorLine, SHORT sKing)
  159.      {
  160.      ARCPARAMS  arcp ;
  161.      AREABUNDLE abnd ;
  162.      LINEBUNDLE lbnd ;
  163.      POINTL     ptl, aptlArc[2] ;
  164.      SHORT      s ;
  165.  
  166.      GpiSavePS (hps) ;
  167.  
  168.                // Set colors for areas and outlines
  169.  
  170.      abnd.lColor = lColor ;
  171.      GpiSetAttrs (hps, PRIM_AREA, ABB_COLOR, 0L, &abnd) ;
  172.  
  173.      lbnd.lColor = lColorLine ;
  174.      GpiSetAttrs (hps, PRIM_LINE, LBB_COLOR, 0L, &lbnd) ;
  175.  
  176.                // Set arc parameters
  177.  
  178.      arcp.lP = PIECE_XAXIS / 2 ;
  179.      arcp.lQ = PIECE_YAXIS / 2 ;
  180.      arcp.lR = 0 ;
  181.      arcp.lS = 0 ;
  182.      GpiSetArcParams (hps, &arcp) ;
  183.  
  184.                // draw the piece
  185.  
  186.      for (s = 0 ; s <= sKing ; s++)
  187.           {
  188.           GpiBeginArea (hps, BA_ALTERNATE | BA_BOUNDARY) ;
  189.  
  190.           ptl.x = 0 ;
  191.           ptl.y = PIECE_YAXIS / 2 + (s + 1) * PIECE_HEIGHT ;
  192.           GpiMove (hps, &ptl) ;
  193.  
  194.           ptl.y -= PIECE_HEIGHT ;
  195.           GpiLine (hps, &ptl) ;
  196.  
  197.           aptlArc[0].x = PIECE_XAXIS / 2 ;
  198.           aptlArc[0].y = s * PIECE_HEIGHT ;
  199.           aptlArc[1].x = PIECE_XAXIS ;
  200.           aptlArc[1].y = PIECE_YAXIS / 2 + s * PIECE_HEIGHT ;
  201.  
  202.           GpiPointArc (hps, aptlArc) ;
  203.  
  204.           ptl.x = PIECE_XAXIS ;
  205.           ptl.y = PIECE_YAXIS / 2 + (s + 1) * PIECE_HEIGHT ;
  206.           GpiLine (hps, &ptl) ;
  207.  
  208.           GpiEndArea (hps) ;
  209.           }
  210.  
  211.      ptl.x = PIECE_XAXIS / 2 ;
  212.      ptl.y = PIECE_YAXIS / 2 + (sKing ? 2 : 1) * PIECE_HEIGHT ;
  213.  
  214.      GpiMove (hps, &ptl) ;
  215.      GpiFullArc (hps, DRO_OUTLINEFILL, MAKEFIXED (1,0)) ;
  216.  
  217.      GpiRestorePS (hps, -1L) ;
  218.      }
  219.  
  220.      /*----------------------------------------------------------
  221.         CkdRenderPieceBitmap: Draws piece on bitmap in memory PS
  222.        ----------------------------------------------------------*/
  223.  
  224. static VOID CkdRenderPieceBitmap (HPS hpsMemory, LONG lColorBack, LONG lColor,
  225.                                   LONG lColorLine, SHORT sKing)
  226.      {
  227.      POINTL ptl ;
  228.  
  229.      GpiSavePS (hpsMemory) ;
  230.  
  231.                // Draw background of bitmap
  232.  
  233.      GpiSetColor (hpsMemory, lColorBack) ;
  234.  
  235.      ptl.x = 0 ;
  236.      ptl.y = 0 ;
  237.      GpiMove (hpsMemory, &ptl) ;
  238.  
  239.      ptl.x = PIECE_XAXIS ;
  240.      ptl.y = PIECE_YAXIS + (sKing + 1) * PIECE_HEIGHT ;
  241.      GpiBox (hpsMemory, DRO_FILL, &ptl, 0L, 0L) ;
  242.  
  243.      CkdRenderPiece (hpsMemory, lColor, lColorLine, sKing) ;
  244.  
  245.      GpiRestorePS (hpsMemory, -1L) ;
  246.      }
  247.  
  248.      /*------------------------------------------------------
  249.         CkdQuerySquareCenter: Obtains center of board square
  250.        ------------------------------------------------------*/
  251.  
  252. static VOID CkdQuerySquareCenter (SHORT x, SHORT y, POINTL *pptlCenter)
  253.      {
  254.      POINTL aptl[4] ;
  255.  
  256.      CkdQuerySquareCoords (x, y, aptl) ;
  257.  
  258.      pptlCenter->x = (aptl[0].x + aptl[1].x + aptl[2].x + aptl[3].x) / 4 ;
  259.      pptlCenter->y = (aptl[1].y + aptl[2].y) / 2 ;
  260.      }
  261.  
  262.      /*---------------------------------------------------------------------
  263.         CkdPieceOriginFromCenter: Converts center of square to piece origin
  264.        ---------------------------------------------------------------------*/
  265.  
  266. static VOID CkdPieceOriginFromCenter (POINTL *pptl)
  267.      {
  268.      pptl->x -= PIECE_XAXIS / 2 ;
  269.      pptl->y -= PIECE_YAXIS / 2 ;
  270.      }
  271.  
  272.      /*-----------------------------------------------------------------
  273.         CkdPieceOriginFromCenter: Same as above, but device coordinates
  274.        -----------------------------------------------------------------*/
  275.  
  276. static VOID CkdPieceOriginFromCenterDevice (POINTL *pptlOrg, POINTL *pptlCntr)
  277.      {
  278.      pptlOrg->x = pptlCntr->x - sizlPiece[0].cx / 2 ;
  279.      pptlOrg->y = pptlCntr->y - sizlPiece[0].cy / 2 ;
  280.      }
  281.  
  282.      /*----------------------------------------------------------------
  283.         CkdQuerySquarePieceOrigin: Obtains origin of piece on a square
  284.        ----------------------------------------------------------------*/
  285.  
  286. static VOID CkdQuerySquarePieceOrigin (SHORT x, SHORT y, POINTL *pptlOrigin)
  287.      {
  288.      CkdQuerySquareCenter (x, y, pptlOrigin) ;
  289.      CkdPieceOriginFromCenter (pptlOrigin) ;
  290.      }
  291.  
  292.      /*-------------------------------------------------------------
  293.         CkdShowPiece: Draws a piece on the screen at specific point
  294.        -------------------------------------------------------------*/
  295.  
  296. static VOID CkdShowPiece (HPS hps, POINTL *pptlOrg, SHORT sColor, SHORT sKing)
  297.      {
  298.      POINTL aptl[3] ;
  299.  
  300.                // Write out mask with bitwise AND
  301.  
  302.      aptl[0]   = *pptlOrg ;
  303.      aptl[1].x = pptlOrg->x + sizlPiece[sKing].cx ;
  304.      aptl[1].y = pptlOrg->y + sizlPiece[sKing].cy ;
  305.      aptl[2].x = 0 ;
  306.      aptl[2].y = 0 ;
  307.  
  308.      GpiSetBitmap (hpsMemory, ahbmMask[sKing]) ;
  309.      GpiBitBlt    (hps, hpsMemory, 3L, aptl, ROP_SRCAND, BBO_IGNORE) ;
  310.  
  311.                // Write out piece with bitwise OR
  312.  
  313.      aptl[0]   = *pptlOrg ;
  314.      aptl[1].x = pptlOrg->x + sizlPiece[sKing].cx ;
  315.      aptl[1].y = pptlOrg->y + sizlPiece[sKing].cy ;
  316.      aptl[2].x = 0 ;
  317.      aptl[2].y = 0 ;
  318.  
  319.      GpiSetBitmap (hpsMemory, ahbmPiece[sColor][sKing]) ;
  320.      GpiBitBlt    (hps, hpsMemory, 3L, aptl, ROP_SRCPAINT, BBO_IGNORE) ;
  321.  
  322.      GpiSetBitmap (hpsMemory, NULL) ;
  323.      }
  324.  
  325.      /*---------------------------------------------------------------------
  326.         CkdDrawOnePiece: Draws a piece on the board at specific coordinates
  327.        ---------------------------------------------------------------------*/
  328.  
  329. static VOID CkdDrawOnePiece (HPS hps, SHORT x, SHORT y,
  330.                              BOARD *pbrd, SHORT sBottom)
  331.      {
  332.      POINTL ptlOrigin ;
  333.      SHORT  i, sKing ;
  334.  
  335.      i = CkdConvertCoordsToIndex (x, y, sBottom) ;
  336.  
  337.      if (i == -1)
  338.           return ;
  339.  
  340.      CkdQuerySquarePieceOrigin (x, y, &ptlOrigin) ;
  341.      GpiConvert (hps, CVTC_PAGE, CVTC_DEVICE, 1L, &ptlOrigin) ;
  342.  
  343.      sKing = pbrd->ulKing & 1L << i ? 1 : 0 ;
  344.  
  345.      if (pbrd->ulBlack & 1L << i)
  346.           CkdShowPiece (hps, &ptlOrigin, BLACK, sKing) ;
  347.  
  348.      if (pbrd->ulWhite & 1L << i)
  349.           CkdShowPiece (hps, &ptlOrigin, WHITE, sKing) ;
  350.      }
  351.  
  352.      /*------------------------------------------------------------------
  353.         CkdPointInsideTrapezoid: Determines if point is inside trapezoid
  354.        ------------------------------------------------------------------*/
  355.  
  356. static BOOL CkdPointInsideTrapezoid (POINTL *pptl, POINTL aptl[])
  357.      {
  358.      if (pptl->x < aptl[0].x || pptl->x >= aptl[1].x)
  359.           return FALSE ;
  360.  
  361.      if (pptl->y < aptl[0].y || pptl->y >= aptl[2].y)
  362.           return FALSE ;
  363.  
  364.      if (pptl->x < (aptl[0].x * (aptl[3].y - pptl->y) +
  365.                     aptl[3].x * (pptl->y - aptl[0].y)) /
  366.                    (aptl[3].y - aptl[0].y))
  367.           return FALSE ;
  368.  
  369.      if (pptl->x >= (aptl[1].x * (aptl[3].y - pptl->y) +
  370.                      aptl[2].x * (pptl->y - aptl[0].y)) /
  371.                     (aptl[3].y - aptl[0].y))
  372.           return FALSE ;
  373.  
  374.      return TRUE ;
  375.      }
  376.  
  377.      /*----------------------------------------------------
  378.         ColorDlgProc: Dialog procedure for changing colors
  379.        ----------------------------------------------------*/
  380.  
  381. MRESULT EXPENTRY ColorDlgProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  382.      {
  383.      static LONG  *pclr ;
  384.      static SHORT sColor ;
  385.      CHAR         *pchHeading ;
  386.  
  387.      switch (msg)
  388.           {
  389.           case WM_INITDLG:
  390.                switch (* (PSHORT) PVOIDFROMMP (mp2))
  391.                     {
  392.                     case IDM_COLOR_BACKGROUND:
  393.                          pchHeading = "Window Background Color" ;
  394.                          pclr = &clrBackground ;
  395.                          break ;
  396.  
  397.                     case IDM_COLOR_BLACK_SQUARE:
  398.                          pchHeading = "Black Square Color" ;
  399.                          pclr = &clrBlackSquare ;
  400.                          break ;
  401.  
  402.                     case IDM_COLOR_WHITE_SQUARE:
  403.                          pchHeading = "White Square Color" ;
  404.                          pclr = &clrWhiteSquare ;
  405.                          break ;
  406.  
  407.                     case IDM_COLOR_BLACK_PIECE:
  408.                          pchHeading = "Black Piece Color" ;
  409.                          pclr = &clrBlackPiece ;
  410.                          break ;
  411.  
  412.                     case IDM_COLOR_WHITE_PIECE:
  413.                          pchHeading = "White Piece Color" ;
  414.                          pclr = &clrWhitePiece ;
  415.                          break ;
  416.                     }
  417.                WinSetDlgItemText (hwnd, IDD_HEADING, pchHeading) ;
  418.  
  419.                sColor = (SHORT) *pclr ;
  420.  
  421.                WinSendDlgItemMsg (hwnd, IDD_COLOR + sColor, BM_SETCHECK,
  422.                                   MPFROM2SHORT (TRUE, 0), NULL) ;
  423.  
  424.                WinSetFocus (HWND_DESKTOP,
  425.                             WinWindowFromID (hwnd, IDD_COLOR + sColor)) ;
  426.  
  427.                return MRFROMSHORT (1) ;
  428.  
  429.           case WM_CONTROL:
  430.                sColor = SHORT1FROMMP (mp1) - IDD_COLOR ;
  431.                return 0 ;
  432.  
  433.           case WM_COMMAND:
  434.                switch (COMMANDMSG(&msg)->cmd)
  435.                     {
  436.                     case DID_OK:
  437.                          *pclr = (LONG) sColor ;
  438.                          WinDismissDlg (hwnd, TRUE) ;
  439.                          return 0 ;
  440.  
  441.                     case DID_CANCEL:
  442.                          WinDismissDlg (hwnd, FALSE) ;
  443.                          return 0 ;
  444.                     }
  445.                break ;
  446.           }
  447.      return WinDefDlgProc (hwnd, msg, mp1, mp2) ;
  448.      }
  449.  
  450.      /*-------------------------------------------------
  451.         CkdCreatePS: Create PS for checker board window
  452.        -------------------------------------------------*/
  453.  
  454. HPS CkdCreatePS (HWND hwnd)
  455.      {
  456.      HDC    hdc ;
  457.      HPS    hps ;
  458.      SIZEL  sizlPage ;
  459.      USHORT sDataSize ;
  460.  
  461.      CkdQueryBoardDimensions (&sizlPage) ;
  462.  
  463.                // Create PS and save original viewport
  464.  
  465.      hdc = WinOpenWindowDC (hwnd) ;
  466.      hps = GpiCreatePS (hab, hdc, &sizlPage,
  467.                         PU_ARBITRARY | GPIF_DEFAULT |
  468.                         GPIT_MICRO   | GPIA_ASSOC) ;
  469.  
  470.      GpiQueryPageViewport (hps, &rclOrigViewport) ;
  471.  
  472.                // Create memory DC's and PS's
  473.  
  474.      hdcMemory  = DevOpenDC (hab, OD_MEMORY, "*", 0L, NULL, NULL) ;
  475.      hpsMemory  = GpiCreatePS (hab, hdcMemory, &sizlPage,
  476.                                PU_ARBITRARY | GPIF_DEFAULT |
  477.                                GPIT_MICRO   | GPIA_ASSOC) ;
  478.  
  479.      hdcMemory2 = DevOpenDC (hab, OD_MEMORY, "*", 0L, NULL, NULL) ;
  480.      hpsMemory2 = GpiCreatePS (hab, hdcMemory2, &sizlPage,
  481.                                PU_ARBITRARY | GPIF_DEFAULT |
  482.                                GPIT_MICRO   | GPIA_ASSOC) ;
  483.  
  484.                // Get colors from OS2.INI
  485.  
  486.      sDataSize = sizeof (LONG) ;
  487.      WinQueryProfileData (hab, szApplication, szClrBackground,
  488.                           &clrBackground, &sDataSize) ;
  489.  
  490.      sDataSize = sizeof (LONG) ;
  491.      WinQueryProfileData (hab, szApplication, szClrBlackSquare,
  492.                           &clrBlackSquare, &sDataSize) ;
  493.  
  494.      sDataSize = sizeof (LONG) ;
  495.      WinQueryProfileData (hab, szApplication, szClrWhiteSquare,
  496.                           &clrWhiteSquare, &sDataSize) ;
  497.  
  498.      sDataSize = sizeof (LONG) ;
  499.      WinQueryProfileData (hab, szApplication, szClrBlackPiece,
  500.                           &clrBlackPiece, &sDataSize) ;
  501.  
  502.      sDataSize = sizeof (LONG) ;
  503.      WinQueryProfileData (hab, szApplication, szClrWhitePiece,
  504.                           &clrWhitePiece, &sDataSize) ;
  505.      return hps ;
  506.      }
  507.  
  508.      /*-------------------------------------------------------
  509.         CkdResizePS: Change page viewport for new window size
  510.        -------------------------------------------------------*/
  511.  
  512. VOID CkdResizePS (HPS hps, HWND hwnd)
  513.      {
  514.      LONG  lScale ;
  515.      RECTL rclWindow, rclViewport ;
  516.  
  517.      WinQueryWindowRect (hwnd, &rclWindow) ;
  518.  
  519.                // Calculate scaling factor
  520.  
  521.      lScale = min (65536L * rclWindow.xRight / rclOrigViewport.xRight,
  522.                    65536L * rclWindow.yTop   / rclOrigViewport.yTop) ;
  523.  
  524.                // Adjust page viewport of window PS
  525.  
  526.      rclViewport.xLeft   = 0 ;
  527.      rclViewport.yBottom = 0 ;
  528.      rclViewport.xRight  = lScale * rclOrigViewport.xRight / 65536L ;
  529.      rclViewport.yTop    = lScale * rclOrigViewport.yTop   / 65536L ;
  530.  
  531.      rclViewport.xLeft   = (rclWindow.xRight - rclViewport.xRight) / 2 ;
  532.      rclViewport.yBottom = (rclWindow.yTop   - rclViewport.yTop)   / 2 ;
  533.      rclViewport.xRight += rclViewport.xLeft ;
  534.      rclViewport.yTop   += rclViewport.yBottom ;
  535.  
  536.      GpiSetPageViewport (hps, &rclViewport) ;
  537.  
  538.                // Similarly for memory PS's
  539.  
  540.      rclViewport.xRight -= rclViewport.xLeft ;
  541.      rclViewport.yTop   -= rclViewport.yBottom ;
  542.      rclViewport.xLeft   = 0 ;
  543.      rclViewport.yBottom = 0 ;
  544.  
  545.      GpiSetPageViewport (hpsMemory,  &rclViewport) ;
  546.      GpiSetPageViewport (hpsMemory2, &rclViewport) ;
  547.      }
  548.  
  549.      /*---------------------------------------------------
  550.         CkdDestroyPS: Destroy PS for checker board window
  551.        ---------------------------------------------------*/
  552.  
  553. BOOL CkdDestroyPS (HPS hps)
  554.      {
  555.                // Save colors in OS2.INI
  556.  
  557.      WinWriteProfileData (hab, szApplication, szClrBackground,
  558.                           &clrBackground, sizeof (LONG)) ;
  559.  
  560.      WinWriteProfileData (hab, szApplication, szClrBlackSquare,
  561.                           &clrBlackSquare, sizeof (LONG)) ;
  562.  
  563.      WinWriteProfileData (hab, szApplication, szClrWhiteSquare,
  564.                           &clrWhiteSquare, sizeof (LONG)) ;
  565.  
  566.      WinWriteProfileData (hab, szApplication, szClrBlackPiece,
  567.                           &clrBlackPiece, sizeof (LONG)) ;
  568.  
  569.      WinWriteProfileData (hab, szApplication, szClrWhitePiece,
  570.                           &clrWhitePiece, sizeof (LONG)) ;
  571.  
  572.                // Destroy memory PS's and close DC's
  573.  
  574.      GpiDestroyPS (hpsMemory) ;
  575.      GpiDestroyPS (hpsMemory2) ;
  576.      DevCloseDC (hdcMemory) ;
  577.      DevCloseDC (hdcMemory2) ;
  578.  
  579.                // Destroy screen PS
  580.  
  581.      return GpiDestroyPS (hps) ;
  582.      }
  583.  
  584.      /*-----------------------------------------------------------
  585.         CkdSetStandardColors: Sets colors to tournament standards
  586.        -----------------------------------------------------------*/
  587.  
  588. VOID CkdSetStandardColors (VOID)
  589.      {
  590.      clrBackground  = CLR_CYAN ;
  591.      clrBlackSquare = CLR_DARKGREEN ;
  592.      clrWhiteSquare = CLR_PALEGRAY ;
  593.      clrBlackPiece  = CLR_RED ;
  594.      clrWhitePiece  = CLR_WHITE ;
  595.      }
  596.  
  597.      /*------------------------------------------------------------
  598.         CkdCreatePieces: Creates bitmaps to use for drawing pieces
  599.        ------------------------------------------------------------*/
  600.  
  601. VOID CkdCreatePieces (HPS hps)
  602.      {
  603.      BITMAPINFOHEADER bmp ;
  604.      LONG             alBitmapFormat[2] ;
  605.      SHORT            sColor, sKing ;
  606.  
  607.                // Get bitmap format of video display
  608.  
  609.      GpiQueryDeviceBitmapFormats (hps, 2L, alBitmapFormat) ;
  610.  
  611.                // Loop through possible color and size combinations
  612.  
  613.      for (sKing = 0 ; sKing < 2 ; sKing++)
  614.           {
  615.                     // Determine pixel dimensions of bitmaps
  616.  
  617.           sizlPiece[sKing].cx = PIECE_XAXIS ;
  618.           sizlPiece[sKing].cy = PIECE_YAXIS + (sKing + 1) * PIECE_HEIGHT ;
  619.  
  620.           GpiConvert (hpsMemory, CVTC_PAGE, CVTC_DEVICE, 1L,
  621.                       (PPOINTL) &sizlPiece[sKing]) ;
  622.  
  623.           sizlPiece[sKing].cx ++ ;
  624.           sizlPiece[sKing].cy ++ ;
  625.           sizlMove[sKing].cx = 2 * sizlPiece[sKing].cx ;
  626.           sizlMove[sKing].cy = 2 * sizlPiece[sKing].cy ;
  627.  
  628.                     // Set up BITMAPINFOHEADER structure
  629.  
  630.           bmp.cbFix     = sizeof bmp ;
  631.           bmp.cx        = (SHORT) sizlPiece[sKing].cx ;
  632.           bmp.cy        = (SHORT) sizlPiece[sKing].cy ;
  633.           bmp.cPlanes   = (SHORT) alBitmapFormat[0] ;
  634.           bmp.cBitCount = (SHORT) alBitmapFormat[1] ;
  635.  
  636.                     // Create ahbmPiece bitmaps
  637.  
  638.           for (sColor = BLACK ; sColor <= WHITE ; sColor++)
  639.                {
  640.                ahbmPiece[sColor][sKing] =
  641.                          GpiCreateBitmap (hps, &bmp, 0L, 0L, NULL) ;
  642.  
  643.                GpiSetBitmap (hpsMemory, ahbmPiece[sColor][sKing]) ;
  644.                CkdRenderPieceBitmap (hpsMemory, CLR_FALSE,
  645.                                sColor ? clrWhitePiece : clrBlackPiece,
  646.                                CLR_BLACK, sKing) ;
  647.                }
  648.  
  649.                     // Create ahbmMask bitmaps
  650.  
  651.           ahbmMask[sKing] = GpiCreateBitmap (hps, &bmp, 0L, 0L, NULL) ;
  652.           GpiSetBitmap (hpsMemory, ahbmMask[sKing]) ;
  653.           CkdRenderPieceBitmap (hpsMemory, CLR_TRUE, CLR_FALSE, CLR_FALSE, sKing) ;
  654.  
  655.                     // Create ahbmSave bitmaps
  656.  
  657.           ahbmSave[sKing] = GpiCreateBitmap (hps, &bmp, 0L, 0L, NULL) ;
  658.  
  659.                     // Create ahbmMove bitmaps
  660.  
  661.           bmp.cbFix     = sizeof bmp ;
  662.           bmp.cx        = (SHORT) sizlMove[sKing].cx ;
  663.           bmp.cy        = (SHORT) sizlMove[sKing].cy ;
  664.           bmp.cPlanes   = (SHORT) alBitmapFormat[0] ;
  665.           bmp.cBitCount = (SHORT) alBitmapFormat[1] ;
  666.  
  667.           ahbmMove[sKing] = GpiCreateBitmap (hps, &bmp, 0L, 0L, NULL) ;
  668.           }
  669.  
  670.      GpiSetBitmap (hpsMemory, NULL) ;
  671.      }
  672.  
  673.      /*---------------------------------------------------
  674.         CkdDestroyPieces: Destroy bitmaps used for pieces
  675.        ---------------------------------------------------*/
  676.  
  677. VOID CkdDestroyPieces (VOID)
  678.      {
  679.      SHORT sColor, sKing ;
  680.  
  681.      for (sKing = 0 ; sKing < 2 ; sKing++)
  682.           {
  683.           for (sColor = BLACK ; sColor <= WHITE ; sColor++)
  684.                if (ahbmPiece[sColor][sKing] != NULL)
  685.                     GpiDeleteBitmap (ahbmPiece[sColor][sKing]) ;
  686.  
  687.           if (ahbmMask[sKing] != NULL)
  688.                GpiDeleteBitmap (ahbmMask[sKing]) ;
  689.  
  690.           if (ahbmSave[sKing] != NULL)
  691.                GpiDeleteBitmap (ahbmSave[sKing]) ;
  692.  
  693.           if (ahbmMove[sKing] != NULL)
  694.                GpiDeleteBitmap (ahbmMove[sKing]) ;
  695.           }
  696.      }
  697.  
  698.      /*--------------------------------------------------------------------
  699.         CkdDrawWindowBackground: Fills entire window with background color
  700.        --------------------------------------------------------------------*/
  701.  
  702. VOID CkdDrawWindowBackground (HPS hps, HWND hwnd)
  703.      {
  704.      RECTL rcl ;
  705.  
  706.      WinQueryWindowRect (hwnd, &rcl) ;
  707.      WinFillRect (hps, &rcl, clrBackground) ;
  708.      }
  709.  
  710.      /*-----------------------------------------------------------
  711.         CkdDrawWholeBoard: Draws the board squares and front edge
  712.        -----------------------------------------------------------*/
  713.  
  714. VOID CkdDrawWholeBoard (HPS hps)
  715.      {
  716.      AREABUNDLE abnd ;
  717.      LINEBUNDLE lbnd ;
  718.      SHORT      x ;
  719.      POINTL     aptl[4] ;
  720.  
  721.      CkdDrawAllBoardSquares (hps) ;
  722.  
  723.      GpiSavePS (hps) ;
  724.  
  725.      lbnd.lColor = CLR_BLACK ;
  726.      GpiSetAttrs (hps, PRIM_LINE, LBB_COLOR, 0L, &lbnd) ;
  727.  
  728.      for (x = 0 ; x < 8 ; x++)
  729.           {
  730.           CkdQuerySquareCoords (x, 0, aptl) ;
  731.  
  732.           aptl[2].x = aptl[1].x ;
  733.           aptl[2].y = aptl[1].y - BRD_EDGE ;
  734.  
  735.           aptl[3].x = aptl[0].x ;
  736.           aptl[3].y = aptl[0].y - BRD_EDGE ;
  737.  
  738.           abnd.lColor = x & 1 ? clrWhiteSquare : clrBlackSquare ;
  739.           GpiSetAttrs (hps, PRIM_AREA, LBB_COLOR, 0L, &abnd) ;
  740.  
  741.           GpiBeginArea (hps, BA_ALTERNATE | BA_BOUNDARY) ;
  742.  
  743.           GpiMove (hps, aptl + 3) ;
  744.           GpiPolyLine (hps, 4L, aptl) ;
  745.  
  746.           GpiEndArea (hps) ;
  747.           }
  748.  
  749.      GpiRestorePS (hps, -1L) ;
  750.      }
  751.  
  752.      /*-----------------------------------------------------
  753.         CkdDrawAllPieces: Draws all the pieces on the board
  754.        -----------------------------------------------------*/
  755.  
  756. VOID CkdDrawAllPieces (HPS hps, BOARD *pbrd, SHORT sBottom)
  757.      {
  758.      SHORT x, y ;
  759.  
  760.      for (y = 0 ; y < 8 ; y++)
  761.           for (x = 0 ; x < 8 ; x++)
  762.                CkdDrawOnePiece (hps, x, y, pbrd, sBottom) ;
  763.      }
  764.  
  765.      /*---------------------------------------------------------------------
  766.         CkdErasePiece: Erases piece from board by drawing the board squares
  767.        ---------------------------------------------------------------------*/
  768.  
  769. VOID CkdErasePiece (HPS hps, SHORT x, SHORT y)
  770.      {
  771.      CkdDrawBoardSquare (hps, x, y + 1) ;
  772.      CkdDrawBoardSquare (hps, x, y) ;
  773.      }
  774.  
  775.      /*---------------------------------------------------------------
  776.         CkdQueryHitCoords: Obtains coords from mouse pointer position
  777.        ---------------------------------------------------------------*/
  778.  
  779. VOID CkdQueryHitCoords (HPS hps, POINTL ptlMouse, SHORT *px, SHORT *py)
  780.      {
  781.      POINTL aptl[4] ;
  782.      SHORT  x, y ;
  783.  
  784.      GpiConvert (hps, CVTC_DEVICE, CVTC_PAGE, 1L, &ptlMouse) ;
  785.  
  786.      for (y = 0 ; y < 8 ; y++)
  787.           for (x = 0 ; x < 8 ; x++)
  788.                {
  789.                CkdQuerySquareCoords (x, y, aptl) ;
  790.                if (CkdPointInsideTrapezoid (&ptlMouse, aptl))
  791.                     {
  792.                     *px = x ;
  793.                     *py = y ;
  794.                     return ;
  795.                     }
  796.                }
  797.  
  798.      *px = -1 ;
  799.      *py = -1 ;
  800.      }
  801.  
  802.      /*-----------------------------------------------------------------------
  803.         CkdConvertCoordsToIndex: Obtains index (0-31) from square coordinates
  804.        -----------------------------------------------------------------------*/
  805.  
  806. SHORT CkdConvertCoordsToIndex (SHORT x, SHORT y, SHORT sBottom)
  807.      {
  808.      if (x < 0 || x > 7 || y < 0 || y > 7)
  809.           return -1 ;
  810.  
  811.      if ((x - (y & 1)) & 1)
  812.           return -1 ;
  813.  
  814.      if (sBottom == WHITE)
  815.           {
  816.           x = 7 - x ;
  817.           y = 7 - y ;
  818.           }
  819.  
  820.      return 3 ^ (4 * y + (x - (y & 1)) / 2) ;
  821.      }
  822.  
  823.      /*-----------------------------------------------------------------------
  824.         CkdConvertIndexToCoords: Obtains square coordinates from index (0-31)
  825.        -----------------------------------------------------------------------*/
  826.  
  827. VOID CkdConvertIndexToCoords (SHORT i, SHORT *px, SHORT *py, SHORT sBottom)
  828.      {
  829.      if (i <= 0 || i >= 32)
  830.           {
  831.           *px = -1 ;
  832.           *py = -1 ;
  833.           }
  834.  
  835.      *py = i / 4 ;
  836.      *px = 2 * ((i ^ 3) % 4) + (*py & 1) ;
  837.  
  838.      if (sBottom == WHITE)
  839.           {
  840.           *px = 7 - *px ;
  841.           *py = 7 - *py ;
  842.           }
  843.      }
  844.  
  845.      /*----------------------------------------------------
  846.         CkdDragSave: Saves screen area when dragging piece
  847.        ----------------------------------------------------*/
  848.  
  849. VOID CkdDragSave (HPS hps, POINTL *pptlMouse, SHORT sKing)
  850.      {
  851.      POINTL ptlOrigin, aptl[3] ;
  852.  
  853.      CkdPieceOriginFromCenterDevice (&ptlOrigin, pptlMouse) ;
  854.  
  855.      aptl[0].x = 0 ;
  856.      aptl[0].y = 0 ;
  857.      aptl[1].x = sizlPiece[sKing].cx ;
  858.      aptl[1].y = sizlPiece[sKing].cy ;
  859.      aptl[2]   = ptlOrigin ;
  860.  
  861.      GpiSetBitmap (hpsMemory, ahbmSave[sKing]) ;
  862.      GpiBitBlt    (hpsMemory, hps, 3L, aptl, ROP_SRCCOPY, BBO_IGNORE) ;
  863.      GpiSetBitmap (hpsMemory, NULL) ;
  864.      }
  865.  
  866.      /*----------------------------------------------------------
  867.         CkdDragRestore: Restores screen area when dragging piece
  868.        ----------------------------------------------------------*/
  869.  
  870. VOID CkdDragRestore (HPS hps, POINTL *pptlMouse, SHORT sKing)
  871.      {
  872.      POINTL ptlOrigin, aptl[3] ;
  873.  
  874.      CkdPieceOriginFromCenterDevice (&ptlOrigin, pptlMouse) ;
  875.  
  876.      aptl[0]   = ptlOrigin ;
  877.      aptl[1].x = ptlOrigin.x + sizlPiece[sKing].cx ;
  878.      aptl[1].y = ptlOrigin.y + sizlPiece[sKing].cy ;
  879.      aptl[2].x = 0 ;
  880.      aptl[2].y = 0 ;
  881.  
  882.      GpiSetBitmap (hpsMemory, ahbmSave[sKing]) ;
  883.      GpiBitBlt    (hps, hpsMemory, 3L, aptl, ROP_SRCCOPY, BBO_IGNORE) ;
  884.      GpiSetBitmap (hpsMemory, NULL) ;
  885.      }
  886.  
  887.      /*-------------------------------------------------------------
  888.         CkdDragShow: Shows piece in new position when being dragged
  889.        -------------------------------------------------------------*/
  890.  
  891. VOID CkdDragShow (HPS hps, POINTL *pptlMouse, SHORT sColor, SHORT sKing)
  892.      {
  893.      POINTL ptlOrigin, aptl[3] ;
  894.  
  895.      CkdPieceOriginFromCenterDevice (&ptlOrigin, pptlMouse) ;
  896.  
  897.                // Write out mask with bitwise AND
  898.  
  899.      aptl[0]   = ptlOrigin ;
  900.      aptl[1].x = ptlOrigin.x + sizlPiece[sKing].cx ;
  901.      aptl[1].y = ptlOrigin.y + sizlPiece[sKing].cy ;
  902.      aptl[2].x = 0 ;
  903.      aptl[2].y = 0 ;
  904.  
  905.      GpiSetBitmap (hpsMemory, ahbmMask[sKing]) ;
  906.      GpiBitBlt    (hps, hpsMemory, 3L, aptl, ROP_SRCAND, BBO_IGNORE) ;
  907.  
  908.                // Write out piece with bitwise OR
  909.  
  910.      aptl[0]   = ptlOrigin ;
  911.      aptl[1].x = ptlOrigin.x + sizlPiece[sKing].cx ;
  912.      aptl[1].y = ptlOrigin.y + sizlPiece[sKing].cy ;
  913.      aptl[2].x = 0 ;
  914.      aptl[2].y = 0 ;
  915.  
  916.      GpiSetBitmap (hpsMemory, ahbmPiece[sColor][sKing]) ;
  917.      GpiBitBlt    (hps, hpsMemory, 3L, aptl, ROP_SRCPAINT, BBO_IGNORE) ;
  918.      GpiSetBitmap (hpsMemory, NULL) ;
  919.      }
  920.  
  921.      /*-------------------------------------------------------------
  922.         CkdDragMove: Moves piece from one part of screen to another
  923.        -------------------------------------------------------------*/
  924.  
  925. VOID CkdDragMove (HPS hps, POINTL *pptlFrom, POINTL *pptlTo,
  926.                            SHORT sColor, SHORT sKing)
  927.      {
  928.      POINTL ptlCenter, ptlOrigin, aptl[3], ptlFrom, ptlTo ;
  929.  
  930.      if ((labs (pptlFrom->x - pptlTo->x) > sizlPiece[sKing].cx) ||
  931.          (labs (pptlFrom->y - pptlTo->y) > sizlPiece[sKing].cy))
  932.           {
  933.           CkdDragRestore (hps, pptlFrom, sKing) ;
  934.           CkdDragSave    (hps, pptlTo,   sKing) ;
  935.           CkdDragShow    (hps, pptlTo,   sColor, sKing) ;
  936.  
  937.           return ;
  938.           }
  939.  
  940.      ptlCenter.x = min (pptlFrom->x, pptlTo->x) ;
  941.      ptlCenter.y = min (pptlFrom->y, pptlTo->y) ;
  942.      CkdPieceOriginFromCenterDevice (&ptlOrigin, &ptlCenter) ;
  943.  
  944.                // Copy screen into ahbmMove bitmap in hpsMemory2
  945.  
  946.      aptl[0].x = 0 ;
  947.      aptl[0].y = 0 ;
  948.      aptl[1].x = sizlMove[sKing].cx ;
  949.      aptl[1].y = sizlMove[sKing].cy ;
  950.      aptl[2]   = ptlOrigin ;
  951.  
  952.      GpiSetBitmap (hpsMemory2, ahbmMove[sKing]) ;
  953.      GpiBitBlt (hpsMemory2, hps, 3L, aptl, ROP_SRCCOPY, BBO_IGNORE) ;
  954.  
  955.                // Do restore, save, & show to hpsMemory2
  956.  
  957.      ptlFrom.x = pptlFrom->x - ptlOrigin.x ;
  958.      ptlFrom.y = pptlFrom->y - ptlOrigin.y ;
  959.      ptlTo.x   = pptlTo->x   - ptlOrigin.x ;
  960.      ptlTo.y   = pptlTo->y   - ptlOrigin.y ;
  961.  
  962.      CkdDragRestore (hpsMemory2, &ptlFrom, sKing) ;
  963.      CkdDragSave    (hpsMemory2, &ptlTo,   sKing) ;
  964.      CkdDragShow    (hpsMemory2, &ptlTo,   sColor, sKing) ;
  965.  
  966.                // Copy ahbmMove bitmap in hpsMemory2 to screen
  967.  
  968.      aptl[0]   = ptlOrigin ;
  969.      aptl[1].x = ptlOrigin.x + sizlMove[sKing].cx ;
  970.      aptl[1].y = ptlOrigin.y + sizlMove[sKing].cy ;
  971.      aptl[2].x = 0 ;
  972.      aptl[2].y = 0 ;
  973.  
  974.      GpiBitBlt (hps, hpsMemory2, 3L, aptl, ROP_SRCCOPY, BBO_IGNORE) ;
  975.      GpiSetBitmap (hpsMemory2, NULL) ;
  976.      }
  977.  
  978.      /*-----------------------------------------------
  979.         CkdDragDeposit: Displays piece at end of drag
  980.        -----------------------------------------------*/
  981.  
  982. VOID CkdDragDeposit (HPS hps, SHORT x, SHORT y, SHORT sColor, SHORT sKing)
  983.      {
  984.      POINTL ptlOrigin ;
  985.  
  986.      CkdQuerySquarePieceOrigin (x, y, &ptlOrigin) ;
  987.      GpiConvert (hps, CVTC_PAGE, CVTC_DEVICE, 1L, &ptlOrigin) ;
  988.      CkdShowPiece (hps, &ptlOrigin, sColor, sKing) ;
  989.      }
  990.  
  991.      /*----------------------------------------------------
  992.         CkdQueryNearestXYFromPoint: For keyboard interface
  993.        ----------------------------------------------------*/
  994.  
  995. VOID CkdQueryNearestXYFromPoint (HPS hps, POINTL *pptlMouse, SHORT *px,
  996.                                                              SHORT *py)
  997.      {
  998.      POINTL ptl, aptlSquare[4] ;
  999.      SHORT  x, y ;
  1000.  
  1001.      ptl = *pptlMouse ;
  1002.      GpiConvert (hps, CVTC_DEVICE, CVTC_PAGE, 1L, &ptl) ;
  1003.  
  1004.      for (y = 0 ; y < 7 ; y++)
  1005.           {
  1006.           CkdQuerySquareCoords (0, y, aptlSquare) ;
  1007.           if (aptlSquare[3].y > ptl.y)
  1008.                break ;
  1009.           }
  1010.  
  1011.      for (x = 0 ; x < 7 ; x++)
  1012.           {
  1013.           CkdQuerySquareCoords (x, y, aptlSquare) ;
  1014.           if ((aptlSquare[0].x + aptlSquare[1].x) / 2 > ptl.x)
  1015.                break ;
  1016.           }
  1017.      *px = x ;
  1018.      *py = y ;
  1019.      }
  1020.  
  1021.      /*----------------------------------------------------
  1022.         CkdSlightOffsetFromXY: For keyboard interface
  1023.        ----------------------------------------------------*/
  1024.  
  1025. VOID CkdQuerySlightOffsetFromXY (HPS hps, SHORT x, SHORT y, POINTL *pptl)
  1026.      {
  1027.      POINTL ptlCenter, ptlOrigin ;
  1028.  
  1029.      CkdQuerySquareCenter (x, y, &ptlCenter) ;
  1030.      CkdQuerySquareOrigin (x, y, &ptlOrigin) ;
  1031.  
  1032.      pptl->x = (3 * ptlCenter.x + ptlOrigin.x) / 4 ;
  1033.      pptl->y = (3 * ptlCenter.y + ptlOrigin.y) / 4 ;
  1034.  
  1035.      GpiConvert (hps, CVTC_PAGE, CVTC_DEVICE, 1L, pptl) ;
  1036.      }
  1037.  
  1038.      /*--------------------------------------------------
  1039.         CkdExternalSave:  Save area (for external moves)
  1040.        --------------------------------------------------*/
  1041.  
  1042. VOID CkdExternalSave (HPS hps, SHORT x, SHORT y, SHORT sKing)
  1043.      {
  1044.      POINTL ptl ;
  1045.  
  1046.      CkdQuerySquareCenter (x, y, &ptl) ;
  1047.      GpiConvert (hps, CVTC_PAGE, CVTC_DEVICE, 1L, &ptl) ;
  1048.      CkdDragSave (hps, &ptl, sKing) ;
  1049.      }
  1050.  
  1051.      /*----------------------------------------------------------
  1052.         CkdExternalShow:  Show piece bitmap (for external moves)
  1053.        ----------------------------------------------------------*/
  1054.  
  1055. VOID CkdExternalShow (HPS hps, SHORT x, SHORT y, SHORT sColor, SHORT sKing)
  1056.      {
  1057.      POINTL ptl ;
  1058.  
  1059.      CkdQuerySquareCenter (x, y, &ptl) ;
  1060.      GpiConvert (hps, CVTC_PAGE, CVTC_DEVICE, 1L, &ptl) ;
  1061.      CkdDragShow (hps, &ptl, sColor, sKing) ;
  1062.      }
  1063.  
  1064.      /*--------------------------------------------------------
  1065.         CkdExternalRestore:  Restore area (for external moves)
  1066.        --------------------------------------------------------*/
  1067.  
  1068. VOID CkdExternalRestore (HPS hps, SHORT x, SHORT y, SHORT sKing)
  1069.      {
  1070.      POINTL ptl ;
  1071.  
  1072.      CkdQuerySquareCenter (x, y, &ptl) ;
  1073.      GpiConvert (hps, CVTC_PAGE, CVTC_DEVICE, 1L, &ptl) ;
  1074.      CkdDragRestore (hps, &ptl, sKing) ;
  1075.      }
  1076.  
  1077.      /*---------------------------------------------------
  1078.         CkdExternalMove:  Move piece (for external moves)
  1079.        ---------------------------------------------------*/
  1080.  
  1081. VOID CkdExternalMove (HPS hps, SHORT sTimerBeg,   SHORT sTimerEnd,
  1082.                                SHORT sTimerColor, SHORT sTimerKing,
  1083.                                SHORT sBottom,     SHORT sTimerInc,
  1084.                                SHORT sTimerSteps)
  1085.      {
  1086.      POINTL ptlBeg, ptlEnd, ptlFrom, ptlTo ;
  1087.      SHORT  x, y ;
  1088.  
  1089.      CkdConvertIndexToCoords (sTimerBeg, &x, &y, sBottom) ;
  1090.      CkdQuerySquareCenter (x, y, &ptlBeg) ;
  1091.      GpiConvert (hps, CVTC_PAGE, CVTC_DEVICE, 1L, &ptlBeg) ;
  1092.  
  1093.      CkdConvertIndexToCoords (sTimerEnd, &x, &y, sBottom) ;
  1094.      CkdQuerySquareCenter (x, y, &ptlEnd) ;
  1095.      GpiConvert (hps, CVTC_PAGE, CVTC_DEVICE, 1L, &ptlEnd) ;
  1096.  
  1097.      ptlFrom.x = ( sTimerInc                * ptlEnd.x +
  1098.                   (sTimerSteps - sTimerInc) * ptlBeg.x) / sTimerSteps ;
  1099.  
  1100.      ptlFrom.y = ( sTimerInc                * ptlEnd.y +
  1101.                   (sTimerSteps - sTimerInc) * ptlBeg.y) / sTimerSteps ;
  1102.  
  1103.      ptlTo.x   = ((sTimerInc + 1)               * ptlEnd.x +
  1104.                   (sTimerSteps - sTimerInc - 1) * ptlBeg.x) / sTimerSteps ;
  1105.  
  1106.      ptlTo.y   = ((sTimerInc + 1)               * ptlEnd.y +
  1107.                   (sTimerSteps - sTimerInc - 1) * ptlBeg.y) / sTimerSteps ;
  1108.  
  1109.      CkdDragMove (hps, &ptlFrom, &ptlTo, sTimerColor, sTimerKing) ;
  1110.      }
  1111.  
  1112.      /*------------------------------------------------------
  1113.         CkdDrawOnePieceDirect:  Draw piece (for setup board)
  1114.        ------------------------------------------------------*/
  1115.  
  1116. VOID CkdDrawOnePieceDirect (HPS hps, SHORT x, SHORT y, BOARD *pbrd,
  1117.                             SHORT sBottom)
  1118.      {
  1119.      MATRIXLF matlf ;
  1120.      POINTL   ptlOrigin ;
  1121.      SHORT    i, sPiece, sKing ;
  1122.      ULONG    ulBit ;
  1123.  
  1124.      i = CkdConvertCoordsToIndex (x, y, sBottom) ;
  1125.  
  1126.      if (i == -1)
  1127.           return ;
  1128.  
  1129.      CkdQuerySquarePieceOrigin (x, y, &ptlOrigin) ;
  1130.  
  1131.      ulBit = 1L <<  i ;
  1132.  
  1133.      if (pbrd->ulBlack & ulBit)
  1134.           sPiece = BLACK ;
  1135.  
  1136.      else if (pbrd->ulWhite & ulBit)
  1137.           sPiece = WHITE ;
  1138.  
  1139.      else
  1140.           return ;
  1141.  
  1142.      sKing = pbrd->ulKing & ulBit ? 1 : 0 ;
  1143.  
  1144.                // Move origin of PS
  1145.  
  1146.      GpiTranslate (hps, &matlf, TRANSFORM_REPLACE, &ptlOrigin) ;
  1147.      GpiSetModelTransformMatrix (hps, 9L, &matlf, TRANSFORM_REPLACE) ;
  1148.  
  1149.                // Render the piece on the board
  1150.  
  1151.      CkdRenderPiece (hps, sPiece ? clrWhitePiece : clrBlackPiece,
  1152.                      CLR_BLACK, sKing) ;
  1153.  
  1154.                // Restore origin of PS
  1155.  
  1156.      GpiSetModelTransformMatrix (hps, 0L, NULL, TRANSFORM_REPLACE) ;
  1157.      }
  1158.  
  1159.      /*------------------------------------------------------------
  1160.         CkdDrawAllPiecesDirect:  Draw all pieces (for setup board)
  1161.        ------------------------------------------------------------*/
  1162.  
  1163. VOID CkdDrawAllPiecesDirect (HPS hps, BOARD *pbrd, SHORT sBottom)
  1164.      {
  1165.      SHORT x, y ;
  1166.  
  1167.      for (y = 0 ; y < 8 ; y++)
  1168.           for (x = 0 ; x < 8 ; x++)
  1169.                CkdDrawOnePieceDirect (hps, x, y, pbrd, sBottom) ;
  1170.      }
  1171.